package lumis.portal.presentation;

/**
 * Enumeration of the possible page doc types.
 *
 * @version $Revision: 11804 $ $Date: 2010-07-29 10:06:21 -0300 (Thu, 29 Jul 2010) $
 * @since 4.1.0
 */
public enum PageDocType
{
	/**
	 * XHTML 1.0 Strict DOCTYPE
	 */
	XHTML10_STRICT("-//W3C//DTD XHTML 1.0 Strict//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"),
	/**
	 * XHTML 1.0 Transitional DOCTYPE
	 */
	XHTML10_TRANSITIONAL("-//W3C//DTD XHTML 1.0 Transitional//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"),
	/**
	 * XHTML 1.0 Frameset DOCTYPE
	 */
	XHTML10_FRAMESET("-//W3C//DTD XHTML 1.0 Frameset//EN", "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd"),
	/**
	 * XHTML 1.1 DTD DOCTYPE
	 */
	XHTML11_DTD("-//W3C//DTD XHTML 1.1//EN", "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"),
	/**
	 * XHTML Basic 1.0 DTD DOCTYPE
	 */
	XHTMLBASIC10_DTD("-//W3C//DTD XHTML Basic 1.0//EN", "http://www.w3.org/TR/xhtml-basic/xhtml-basic10.dtd"),
	/**
	 * XHTML Basic 1.1 DTD DOCTYPE
	 */
	XHTMLBASIC11_DTD("-//W3C//DTD XHTML Basic 1.1//EN", "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd"),
	/**
	 * HTML 4.01 Strict DOCTYPE
	 */
	HTML401_STRICT("-//W3C//DTD HTML 4.01//EN", "http://www.w3.org/TR/html4/strict.dtd"),
	/**
	 * HTML 4.01 Transitional DOCTYPE
	 */
	HTML401_TRANSITIONAL("-//W3C//DTD HTML 4.01 Transitional//EN", "http://www.w3.org/TR/html4/loose.dtd"),
	/**
	 * HTML 4.01 Frameset DOCTYPE
	 */
	HTML401_FRAMESET("-//W3C//DTD HTML 4.01 Frameset//EN", "http://www.w3.org/TR/html4/frameset.dtd"),
	/**
	 * HTML 2.0 DTD DOCTYPE
	 */
	HTML20_DTD("-//IETF//DTD HTML 2.0//EN", null),
	/**
	 * HTML 3.2 DTD DOCTYPE
	 */
	HTML32_DTD("-//W3C//DTD HTML 3.2 Final//EN", null),
	/**
	 * Do not specify a Doctype
	 */
	NONE("");

	private final String docTypeDeclaration;
	
	/**
	 * The public DTD name for the doctype.
	 * @since 5.6.0
	 */
	private final String publicDTDName;

	/**
	 * Constructs a new PageDocType without a DTD.
	 * @param docTypeDeclaration the doctype declaration.
	 * @since 4.1.0
	 */
	private PageDocType(String docTypeDeclaration)
	{
		this.docTypeDeclaration = docTypeDeclaration;
		this.publicDTDName = null;
	}
	
	/**
	 * Constructs a new PageDocType with a public DTD name and optionally
	 * a DTD URI.
	 * @param publicDTDName the public DTD name.
	 * @param dtdURI the URI for the DTD.
	 * @since 5.6.0
	 */
	private PageDocType(String publicDTDName, String dtdURI)
	{
		this.publicDTDName = publicDTDName;
		this.docTypeDeclaration = "<!DOCTYPE html PUBLIC \"" + publicDTDName + "\"" + (dtdURI != null ? " \"" + dtdURI + "\"":"") + ">";
	}

	public String getDocTypeDeclaration()
	{
		return docTypeDeclaration;
	}

	public static PageDocType getPageDocTypeByName(String pageDocTypeName)
	{
		return Enum.valueOf(PageDocType.class, pageDocTypeName);
	}
	
	/**
	 * Returns the {@link PageDocType} for a public DTD name.
	 * @param publicDTDName the public DTD name for the doctype.
	 * @return the <code>PageDocType</code> or <code>null</code> if none was
	 * found.
	 * @throws IllegalArgumentException if <code>publicDTDName</code> is <code>null</code>.
	 * @since 5.6.0
	 */
	public static PageDocType getPageDocTypeByPublicDTDName(String publicDTDName)
	{
		if (publicDTDName == null)
			throw new IllegalArgumentException("publicDTDName cannot be null");
		
		for (PageDocType pageDocType: values())
			if (publicDTDName.equals(pageDocType.publicDTDName))
				return pageDocType;
		return null;
	}

	/**
	 * Depending on the DOCType, the closing xml tags may be in different formats.
	 * 
	 * @param tagValue
	 * @return
	 * @since 4.1.0
	 */
	public String formatW3CClosedTag(String tagValue)
	{
		if (isXHTML())
			return "<" + tagValue + "/>";
		else
			return "<" + tagValue + ">";
	}
	
	/**
	 * Returns whether this doctype is a XHTML doctype.
	 * @return <code>true</code> if this is a XHTML doctype, <code>false</code>
	 * otherwise.
	 * @since 5.6.0
	 */
	public boolean isXHTML()
	{
		switch (this)
		{
			case XHTML10_STRICT:
			case XHTML10_TRANSITIONAL:
			case XHTML10_FRAMESET:
			case XHTML11_DTD:
			case XHTMLBASIC10_DTD:
			case XHTMLBASIC11_DTD:
				return true;
			default:
				return false;
		}
	}
}
